import turfClass from './turf.js'
class OL_MAP{
  constructor(options){
      this.zoom=options.zoom||19;
      this.maxZoom=options.maxZoom||22;
      this.minZoom=options.minZoom||12;
      this.center=options.center||null;
      this.target1=options.target1
      this.target2=options.target2

      this.olMap1=undefined
      this.olMap2=undefined
      this.layers1=options.layers1||[]
      this.layers2=options.layers2||[]
      this.InitMap();

      this.swip_layer_index=options.swip_layer_index||0;
      this.swip_layer_lst_xy=[];
      this.draw_map_id=options.draw_map_id||1;
      this.draw=null
      this.drawing=false


      this.layer2_show_featrue_layer=null
      this.layer2_show_featrue_selects=[]
      this.layer2_show_featrue_drawlayer=null

      this.moveend_refresh={
        status:false,
        cb:undefined
      }
      this.click_featrue={
        status:false,
        cb:undefined
      }
      this.moveend_refresh=false
  }
  set(name,value,cb=undefined){
    this[name]={
      status:value,
      cb:cb
    }
  }
  InitMap(){
    let View_option={
      projection:'EPSG:4326',
      zoom: this.zoom,
      maxZoom: this.maxZoom,
      enableRotation: false
    }
    if(this.center){
      View_option.center=this.center
    }
    let view=new ol.View(View_option)
    if(this.target1){
      this.olMap1= new ol.Map({
        layers: this.layers1,
        target: this.target1,
        view: view
      });
    }
    if(this.target2){
      this.olMap2= new ol.Map({
        layers: this.layers2,
        target: this.target2,
        view: view,
        controls: [],
      });
    }
    this.olMap1.removeInteraction(this.olMap1.getInteractions().getArray().find(interaction => {
      return interaction instanceof ol.interaction.DoubleClickZoom;
    }));
    this.olMap1.removeInteraction(this.olMap1.getInteractions().getArray().find(interaction => {
      return interaction instanceof ol.interaction.DragRotate;
    }));
    this.olMap1.removeInteraction(this.olMap1.getInteractions().getArray().find(interaction => {
      return interaction instanceof ol.interaction.PinchRotate;
    }));
    if(this.olMap2){
      this.olMap2.removeInteraction(this.olMap2.getInteractions().getArray().find(interaction => {
        return interaction instanceof ol.interaction.DoubleClickZoom;
      }));
      this.olMap2.removeInteraction(this.olMap2.getInteractions().getArray().find(interaction => {
        return interaction instanceof ol.interaction.DragRotate;
      }));
      this.olMap2.removeInteraction(this.olMap2.getInteractions().getArray().find(interaction => {
        return interaction instanceof ol.interaction.PinchRotate;
      }));
    }
    if(this.olMap1){
      this.onclick()
      this.onmoveend()
      this.onpointermove()
    }
    this.olMap1.addControl(new ol.control.MousePosition({
      coordinateFormat:ol.coordinate.createStringXY(3),
      projection:"EPSG:4326",
      className:"standard-map__mouse-position",
      target:document.getElementById(this.target1),
      undefinedHTML:"0,0"
    }));
  }
  SwipeLayer(xy){
    if(this.swip_layer_index){
      if(xy){
        this.swip_layer_lst_xy=xy
      }
      else{
        xy=this.swip_layer_lst_xy
      }
      if(xy.length==2){
        let pos =this.olMap1.getCoordinateFromPixel(xy)//将屏幕坐标 转换为 地图坐标
        this.layers1[this.swip_layer_index].setExtent([0, 0, pos[0], pos[1]])
        let MapObject=this.GetMapObject(1)
        if(MapObject){
          MapObject.render()
        }
      }
      
    }
  }
  update_layer(layers1,num){
    let MapObject=this.GetMapObject(num)
    if(MapObject){
      MapObject.setLayers(layers1)
    }
  }
  update_center(center){
    let MapObject=this.GetMapObject(1)
    if(MapObject){
      MapObject.getView().setCenter(center)
    }
  }
  GetMapObject(map){
    if(map==1){
      return this["olMap1"]
    }
    else if(map==2){
      return this["olMap2"]
    }
  }
  clearMap(map){
    if(map==1 ||map==2){
      let _MapObject=this.GetMapObject(map)
      if(_MapObject){
        let layers=_MapObject.getLayers()
        let length=layers.getLength()
        for (let index = 0; index < length; index++) {
          _MapObject.removeLayer(layers.item(index))
        }
      }
    }
    this.layer2_show_featrue_layer=null
  }
  async SetImage(url,extend,map,imageSize=[512,512]){
    if(imageSize.length==0){
      imageSize=[512,512]
    }
    let ImageLayer=new ol.layer.Image({
        source:new ol.source.ImageStatic({
          url: url,
          imageExtent: extend,
          imageSize:imageSize
      })
    });
    let MapObject=this.GetMapObject(map)
    if(MapObject){
      this.clearMap(map)
      MapObject.addLayer(ImageLayer);
      MapObject.updateSize();
    }
  }
  async SetFeatrue(rings,map,other=null){
    let FeatrueSource = new ol.source.Vector({
      features:[]
    });
    let layer_Vector=new ol.layer.Vector({
      source: FeatrueSource,
    })
    try{
      //let Polygon=undefined
      let Style=new ol.style.Style({
        fill:new ol.style.Fill({ 
          color:[79, 164, 206, 0]
        }),
        stroke:  new ol.style.Stroke({ 
          color:[24, 144, 255, 1],
          width:2
        }),
      })
      for (let index = 0; index < rings.length; index++) {
        let _ring=rings[index]
        let _py=new ol.geom.Polygon([_ring])
        let feature=new ol.Feature({
          geometry:_py,
        });
        feature.setStyle(Style)
        FeatrueSource.addFeature(feature)
      }
      let MapObject=this.GetMapObject(map)
      if(map==2){
        this.layer2_show_featrue_layer=layer_Vector
        //this.layer2_show_draw=null
      }
      if(MapObject){
        MapObject.addLayer(layer_Vector)
        let Polygon_extend=FeatrueSource.getExtent();
        MapObject.getView().fit(Polygon_extend,{
          duration:100,
          maxZoom:this.zoom
        })
        MapObject.other=other
      }
    }
    catch(error){
      console.log(error.message)
    }
  }
  Featrue_common_style(){
    return new ol.style.Style({
      fill:new ol.style.Fill({ 
        color:[79, 164, 206, 0]
      }),
      stroke:  new ol.style.Stroke({ 
        color:[216, 38, 38, 1],
        width:2
      }),
    })
  }
  Featrue_select_style(){
    return new ol.style.Style({
      fill:new ol.style.Fill({ 
        color:[79, 164, 206, 0]
      }),
      stroke:  new ol.style.Stroke({ 
        color:[24, 144, 255, 1],
        width:2
      }),
    })
  }
  Featrue_set_style(clicked=false){
    for (let index = 0; index < this.layer2_show_featrue_selects.length; index++) {
      let one_fc = this.layer2_show_featrue_selects[index];
      if(clicked){
        one_fc.setStyle(this.Featrue_select_style())
      }
      else{
        one_fc.setStyle(this.Featrue_common_style())
      }
    }
  }
  addFeatrue(_json_fcs,clear=false){
    if(this.layer2_show_featrue_layer==null ){
      this.layer2_show_featrue_source = new ol.source.Vector({
        features:[]
      });
      this.layer2_show_featrue_layer=new ol.layer.Vector({
        source: this.layer2_show_featrue_source,
      })
      for(let i=1;i <=2;i++){
        let MapObject=this.GetMapObject(i)
        if(MapObject){
          MapObject.addLayer(this.layer2_show_featrue_layer)
        }
      }
    }
    if(clear){
      this.layer2_show_featrue_source.clear()
    }
    console.log(_json_fcs.length)
    for(let i=0;i <_json_fcs.length;i++){
      let one_fc=_json_fcs[i]
      let _py=new ol.geom.Polygon(one_fc.geometry.coordinates)
      let feature=new ol.Feature({
        geometry:_py,
        properties:one_fc.properties,
        extent:_py.getExtent()
      });
      feature.setId(one_fc.properties.JVBH)
      feature.setStyle(this.Featrue_common_style())
      this.layer2_show_featrue_source.addFeature(feature)
    }
    let MapObject=this.GetMapObject(1)
    if(MapObject){
      MapObject.render()
    }
  }
  get_Featrue_Coordinates(fc){
    return fc.getGeometry().getCoordinates()
  }
  get_Featrue_area(fc){
    return fc.getGeometry().clone().transform("EPSG:4326",'EPSG:3857').getArea()
  }
  get_Featrue_Properties(fc){
    if(Array.isArray(fc)){
      let jsvhs=[]
      for (let index = 0; index < fc.length; index++) {
        let element = fc[index];
        jsvhs.push(element.getProperties().properties.JVBH)
      }
      return jsvhs
    }
    else{
      return fc.getProperties().properties.JVBH
    }
  } 
  zoom_to_feature({JVBH}){
    let _Source=this.layer2_show_featrue_layer.getSource()
    let Polygon_extend=undefined
    if(JVBH){
      let fc=_Source.getFeatureById(JVBH)
      if(fc){
        Polygon_extend=fc.getProperties().extent
      }
    }
    if(Polygon_extend){
      let MapObject=this.GetMapObject(1)
        if(MapObject){
          MapObject.getView().fit(Polygon_extend,{
            duration:200,
            zoom:15
          })
        }
    }
  }     
  static GetTileLayer(url,options){
    // let xyz={url,}
    let xyz={}
    if(options.projection){
      xyz.projection=options.projection
    }
    if(options.tileSize){
      xyz.tileSize=options.tileSize
    }
    if(options.maxResolution){
      xyz.maxResolution=options.maxResolution
    }
    if(options.wrapX){
      xyz.wrapX=options.wrapX
    }
    if(options.tileLoadFunction){
      xyz.tileLoadFunction=options.tileLoadFunction
    }
    
    if(!xyz.url){
      xyz.tileUrlFunction=function([z,Col,Row],b){
        let _url=this.urlx
        //console.log(_url,z,Col,Row)
        return _url.replace("{z}",z-1).replace("{x}",Col).replace("{y}",Row)
      }
      // ([z,Col,Row],b)=>{
       
      // }
    }
    // tileUrlFunction
    // xyz.zDirection=1
    let xzy= new ol.source.XYZ(xyz)
    xzy.urlx=url
    let tile_layer=new ol.layer.Tile({
      source: xzy,
    })
    if(options.properties){
      for (let [key, value] of Object.entries(options.properties)) {
        tile_layer.set(key,value)
      }
    }
    return tile_layer
  }
  setZoom(zoom){
      let _set_zoom=this.GetMapObject(1).getView().getZoom()
      if(zoom>0){
        if(_set_zoom>=this.maxZoom){_set_zoom=this.maxZoom}
        else{
          _set_zoom=_set_zoom+1
        }
      }
      else{
        if(_set_zoom<=this.minZoom){
          _set_zoom=this.minZoom
        }
        else{
          _set_zoom=_set_zoom-1
        }
      }
      this.GetMapObject(1).getView().setZoom(_set_zoom)
  }
  upDate(){
    this.GetMapObject(1).updateSize()
    if(this.GetMapObject(2)){
      this.GetMapObject(2).updateSize()
    }
  }
  DrawStyle(){
    return new ol.style.Style({
      fill:new ol.style.Fill({ 
        color:[79, 164, 206, 0]
      }),
      stroke:  new ol.style.Stroke({ 
        color:[255, 77, 79, 1],
        width:1.5
      }),
    })
  }
  initDraw(cb){
    if(this.layer2_show_featrue_drawlayer==null){
      let FeatrueSource = new ol.source.Vector({
        wrapX: false,
        features:[]
      });
      this.layer2_show_featrue_drawlayer=new ol.layer.Vector({
        source: FeatrueSource,
      })
      this.layer2_show_featrue_drawlayer.setStyle(new ol.style.Style({
        fill:new ol.style.Fill({ 
          color:[79, 164, 206, 0]
        }),
        stroke:  new ol.style.Stroke({ 
          color:[24, 144, 255, 0.5],
          width:0.5
        }),
      }))
      for(let i=1;i <=2;i++){
        let MapObject=this.GetMapObject(i)
        if(MapObject){
          MapObject.addLayer(this.layer2_show_featrue_drawlayer)
        }
      }
    }
    if(this.draw){
      this.GetMapObject(1).removeInteraction(this.draw);
      this.draw=undefined
      return false
    }
    else{
      this.draw= new ol.interaction.Draw({
        source: this.layer2_show_featrue_drawlayer.getSource(),
        freehand:false,
        type: "Polygon",
        // style:this.DrawStyle()
      });
      this.draw.on("drawstart",()=>{
        this.drawing=true
      })
      this.draw.on("drawend",(drawend_val)=>{
        this.layer2_show_featrue_drawlayer.setStyle(this.DrawStyle())
        setTimeout(() => {
          this.drawing=false
        }, 1000);
        this.get_other_fc(drawend_val.feature,cb)
      })
      this.draw.on("drawabort",()=>{
        setTimeout(() => {
          this.drawing=false
        }, 1000);
      })
      this.GetMapObject(1).addInteraction(this.draw);
      return true
    }
  }
  abortDrawing(){
    this.draw.abortDrawing()
  }
  clearDrawLayer(){
    this.layer2_show_featrue_drawlayer.getSource().clear()
  }
  get_other_fc(_fc,cb){
    let _fc_geom=_fc.getGeometry()
    let _Source=this.layer2_show_featrue_layer.getSource()
    let valus=_Source.getFeatures().filter((val)=>{
      let geom=val.getGeometry()
      return turfClass.Check_Contain_Intersect(_fc_geom.getCoordinates(),geom.getCoordinates())
    })
    if(typeof cb==="function"){
      cb(_fc,this.get_Featrue_Properties(valus))
    }
  }
  onclick(){
    this.onclick_call(1)
  }
  onclick_call(num=1){
    let that=this;
    let MapObject=this.GetMapObject(num)
    if(MapObject){
      MapObject.on('click', (event)=>{
        if(that.drawing==false && that.click_featrue.status){
          if(MapObject.hasFeatureAtPixel(event.pixel)){
            let Features=MapObject.getFeaturesAtPixel(event.pixel)
            that.Featrue_set_style(false)
            that.layer2_show_featrue_selects=Features
            that.Featrue_set_style(true)
            if(typeof that.click_featrue.cb==="function"){
              that.click_featrue.cb(Features[0].getProperties())
            }
          }
          else{
            that.Featrue_set_style(false)
            that.layer2_show_featrue_selects=[]
            if(typeof that.click_featrue.cb==="function"){
              that.click_featrue.cb({})
            }
          }
        }
      });
    }
  }
  onpointermove(){
    let that=this;
    let MapObject=this.GetMapObject(1)
    if(MapObject){
      MapObject.on('pointermove', ()=>{
        that.SwipeLayer()
      });
    }
  }
  onmoveend(){
    this.onmoveend_call(1)
  }
  onmoveend_call(num=1){
    let that=this;
    let MapObject=this.GetMapObject(num)
    if(MapObject){
      MapObject.on('moveend', ()=>{
        that.force_moveend(MapObject)
      });
    }
  }
  force_moveend(MapObject){
    let that=this;
    if(!MapObject){
      MapObject=this.GetMapObject(1)
    }
    if(MapObject){
      if(that.moveend_refresh.status){
        if(that.layer2_show_featrue_layer){
          let _Source=that.layer2_show_featrue_layer.getSource()
          let extent=MapObject.getView().calculateExtent()
          let Extent_fcs=_Source.getFeaturesInExtent(extent)
          let jsvhs=that.get_Featrue_Properties(Extent_fcs)
          if(typeof that.moveend_refresh.cb==="function"){
            that.moveend_refresh.cb(jsvhs)
          }
        }
      }
    }
    
  }
}
export default OL_MAP;